package core.connector.email.http.r7;

import gui.factory.components.AbstractDownload;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import core.connector.ConnectionDetails;
import core.connector.DownloadableItem;
import core.connector.email.Email;
import core.connector.email.http.HttpConnectorBase;
import core.util.IOutils;
import core.util.JGoogleAnalytics;

public class HttpConnectorR7 extends HttpConnectorBase{

	public HttpConnectorR7(ConnectionDetails connectionDetails) {
		super(connectionDetails);
		JGoogleAnalytics.trackAsynchronously("Connector HTTP - R7");
	}

	@Override
	public boolean connect() {
		
		System.out.println("CONECTANDO...");
        if (user.equals("") || passwd.equals("")){
            throw new IllegalStateException("Cannot connect: user and password not specified.");
        }
		
        int domain;
        if((domain = user.indexOf("@")) > -1){
        	user = user.substring(0,domain);
        }
        
        boolean sucess = false;
        
		PostMethod post = new PostMethod("https://login.r7.com/login");
        post.addRequestHeader("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png;q=0.5");
        post.addRequestHeader("Connection", "keep-alive");
        post.addRequestHeader("Accept-Encoding", "gzip, deflate");
        post.addRequestHeader("Referer", "http://email.r7.com/login");
        post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        post.addParameter("user.login", user);
        post.addParameter("user.password", passwd);
        post.addParameter("kaptcha", "");
        post.addParameter("href", "http://webmail.r7.com/");
        setCookies(post);      
        
        try{
            client.executeMethod(post);            
            Header location = post.getResponseHeader("location");            
            if(location != null && location.getValue().contains("login")){
            	throw new RuntimeException("Login ou senha incorretos");
            }
            handleCookies(post);
            folowRedirects(post, true);
            this.status = HttpConnectorBase.STATUS_CONNECTED;
            sucess = true;
        }catch (Exception ex){
            ex.printStackTrace();
        }        
		return sucess;
	}

	@Override
	public void disconnect() {
		
		System.out.println("DESCONECTANDO...");
		
		GetMethod get = new GetMethod("http://webmail.r7.com/services/ajax.php/imp/logOut");
		get.addRequestHeader("Accept","text/html,application/xhtml+xml,application/xml");
		get.addRequestHeader("Accept-Language","pt-br;en-us");
		get.addRequestHeader("Accept-Encoding","gzip");
		get.addRequestHeader("Accept-Charset","ISO-8859-1,utf-8");
		get.addRequestHeader("Connection","keep-alive");
		get.addRequestHeader("Referer","http://webmail.r7.com/c3mail/");
		setCookies(get);
		
		try {
			client.executeMethod(get);
            handleCookies(get);
            folowRedirects(get, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.status = HttpConnectorBase.STATUS_NOT_INIT;
		clearCookie();		
	}

	@Override
	public void getFile(DownloadableItem email, File pastaDestino,AbstractDownload downloadGUI) throws IOException, ProtocolException, UnknownHostException, Exception {
		String link = "http://webmail.r7.com/services/download/?module=imp&actionID=download_attach&id=1&uid="+email.getFileId()+"&mailbox=INBOX";
		
		System.out.println("RECEBENDO ARQUIVO...");
		
		GetMethod get = new GetMethod(link);
		get.addRequestHeader("Accept","text/html,application/xhtml+xml,application/xml");
		get.addRequestHeader("Accept-Language","pt-br;en-us");
		//get.addRequestHeader("Accept-Encoding","gzip");
		get.addRequestHeader("Accept-Charset","ISO-8859-1,utf-8");
		get.addRequestHeader("Connection","keep-alive");
		get.addRequestHeader("Referer","http://webmail.r7.com/c3mail/");
		setCookies(get);
		
		BufferedInputStream in = null;
		int response;
		
		try {
			response = client.executeMethod(get);			
			if(response == HttpStatus.SC_OK){
				Header ct = get.getResponseHeader("Content-Type");
				if(ct != null && ct.getValue().contains("application")){
					in = new BufferedInputStream(get.getResponseBodyAsStream());
					String filename = resolveFileName(email, get);
					IOutils.saveToFile(filename, in, pastaDestino, downloadGUI);
				}
			}
		} catch (Exception e) {
			throw e;
		}	
		
	}

	@Override
	public boolean getNextFile() throws Exception {
		
		System.out.println("LISTANDO...");
		
		PostMethod post = new PostMethod("http://webmail.r7.com/services/ajax.php/imp/viewPort");
        post.addRequestHeader("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png;q=0.5");
        post.addRequestHeader("Connection", "keep-alive");
        post.addRequestHeader("Accept-Encoding", "gzip, deflate");
        post.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        post.addRequestHeader("X-Prototype-Version", "1.6.1");            
        post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        post.addRequestHeader("Referer", "http://webmail.r7.com/c3mail/");
        
        post.addParameter("view", "INBOX");
        post.addParameter("requestid", "1");
        post.addParameter("initial", "1");
        post.addParameter("after", "1");
        post.addParameter("before", "1000");
        post.addParameter("slice", "1:1000");
        setCookies(post);
        
        String resultado = null;
        
        try{
        	client.executeMethod(post);            
        	resultado = getResponseBodyAsString(post);
        }catch (Exception e) {
        	e.printStackTrace();
		}
        
        if(resultado != null){
        	Map<String,MailEntry> emails = getEntries(resultado);
        	Iterator<Entry<String, MailEntry>> i = emails.entrySet().iterator();
        	while(i.hasNext()){
        		MailEntry entry = i.next().getValue();
        		String[] size = entry.getSize().trim().split(" ");
        		float tam = DownloadableItem.UNKNOW_SIZE;
        		if(size.length == 2){
        			tam = Float.parseFloat(size[0].replace(",", "."));
        			if(size[1].equalsIgnoreCase("mb")){
        				tam *= (1024 * 1024);
        			}else if(size[1].equalsIgnoreCase("kb")){
        				tam *= 1024;
        			}
        		}
        		long length = (long) (tam/ 1.3699999999999999D);
        		this.addFile(new Email(entry.getFilename(), String.valueOf(entry.getId()), length));
        	}
        }
		return false;
	}

	private Map<String, MailEntry> getEntries(String resultado)	throws ScriptException {
		Map<String, MailEntry> emails = new LinkedHashMap<String,MailEntry>();
		int rini = resultado.indexOf("/*-secure-")+10;
		if(rini > 0){
			resultado = "mb="+resultado.trim().substring(rini,resultado.length()-3);
		    ScriptEngineManager mgr = new ScriptEngineManager();
		    ScriptEngine engine = mgr.getEngineByName("JavaScript");	            
		    engine.eval(resultado);
		    engine.put("emails", emails);
		    engine.eval(
		    		"importClass(Packages.core.connector.email.http.r7.MailEntry);"+
		            "var list = mb.response.ViewPort.data;"+
		            "var ident;"+
		            "for(ident in list){"+
		            "  var entry = list[ident];"+
		            "  emails.put(entry,new MailEntry(entry.subject,entry.size,entry.imapuid));"+
		            "}");
		}
		return emails;
	}

	@Override
	public int getNumberOfFiles() {
		return 0;
	}
	
}
